package com.ly.heart.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ly.common.PageParam;
import com.ly.common.core.domain.AjaxResult;
import com.ly.common.core.domain.entity.SysDept;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.StringUtils;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.*;
import com.ly.heart.domain.dto.MateriaDto;
import com.ly.heart.domain.dto.MaterialAddDto;
import com.ly.heart.domain.vo.ImportMaterialVo;
import com.ly.heart.domain.vo.MateriaVo;
import com.ly.heart.service.*;
import com.ly.heart.util.ChineseToPinyin;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.system.service.ISysDeptService;
import org.springframework.stereotype.Service;
import com.ly.heart.mapper.MaterialMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 物料信息Service业务层处理
 * @author cxl
 * @date 2024-05-14
 */
@Service
public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, MaterialEntity> implements IMaterialService {

    @Resource
    private MaterialMapper materialEntityMapper;

    @Resource
    private IMaterialSaleService materialSaleService;

    @Resource
    private IMaterialProcureService materialProcureService;

    @Resource
    private IMaterialProductService materialProductService;

    @Resource
    private IMaterialInventoryService materialInventoryService;

    @Resource
    private IMaterialQualityService materialQualityService;

    @Resource
    private IMaterialPlanAttributeService materialPlanAttributeService;

    @Resource
    private IKingBaseMeteringUnitService iKingBaseMeteringUnitService;

    @Resource
    private ISysDeptService sysDeptService;
    @Resource
    private IKingBaseTaxRateService iKingBaseTaxRateService;

    /**
     * 查询物料信息
     * @param id 物料信息主键
     * @return 物料信息
     */
    @Override
    public MaterialEntity selectMaterialEntityById (String id) {
        return materialEntityMapper.selectMaterialEntityById ( id );
    }

    /**
     * 查询物料信息列表
     * @param materiaDto 物料信息
     * @return 物料信息
     */
    @Override
    public IPage<MateriaVo> selectMaterialEntityList (MateriaDto materiaDto) {

        IPage<MateriaVo> materiaVoIPage = materialEntityMapper.selectMaterialEntityList ( materiaDto );

        return materiaVoIPage;
    }


    /**
     * 新增物料信息
     * @param materialAddDto 物料信息
     * @return 结果
     */
    @Override
    @Transactional (rollbackFor = Exception.class)
    public AjaxResult insertMaterialEntity (MaterialAddDto materialAddDto) {
        Date nowDate = DateUtils.getNowDate ();
        String materialId = SnowflakeIdWorker.getInstance ().nextStringId ();
        MaterialEntity materialEntity = materialAddDto.getMaterialEntity ();
        materialEntity.setId ( materialId );
        materialEntity.setCreateTime ( nowDate );

        //物料销售基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialSaleEntity () ) ) {
            MaterialSaleEntity materialSaleEntity = materialAddDto.getMaterialSaleEntity ();
            materialSaleEntity.setMaterialId ( materialEntity.getId () );
            materialSaleEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean saved = materialSaleService.save ( materialSaleEntity );
            if ( ! saved ) {
                return AjaxResult.error ( "新增物料销售信息失败" );
            }
        }
        //物料采购基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialProcureEntity () ) ) {
            MaterialProcureEntity materialProcureEntity = materialAddDto.getMaterialProcureEntity ();
            materialProcureEntity.setMaterialId ( materialEntity.getId () );
            materialProcureEntity.setCreateTime ( nowDate );
            materialProcureEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean save = materialProcureService.save ( materialProcureEntity );
            if ( ! save ) {
                return AjaxResult.error ( "新增物料采购信息失败" );
            }
        }
        //物料生产基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialProductEntity () ) ) {
            MaterialProductEntity materialProductEntity = materialAddDto.getMaterialProductEntity ();
            materialProductEntity.setMaterialId ( materialEntity.getId () );
            materialProductEntity.setCreateTime ( nowDate );
            materialProductEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean save = materialProductService.save ( materialProductEntity );
            if ( ! save ) {
                return AjaxResult.error ( "新增物料生产信息失败" );
            }
        }
        //物料库存基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialInventoryEntity () ) ) {
            MaterialInventoryEntity materialInventoryEntity = materialAddDto.getMaterialInventoryEntity ();
            materialInventoryEntity.setMaterialId ( materialEntity.getId () );
            materialInventoryEntity.setCreateTime ( nowDate );
            materialInventoryEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean save = materialInventoryService.save ( materialInventoryEntity );
            if ( ! save ) {
                return AjaxResult.error ( "新增物料库存信息失败" );
            }
        }
        //物料质量基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialQualityEntity () ) ) {
            MaterialQualityEntity materialQualityEntity = materialAddDto.getMaterialQualityEntity ();
            materialQualityEntity.setMaterialId ( materialEntity.getId () );
            materialQualityEntity.setCreateTime ( nowDate );
            materialQualityEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean save = materialQualityService.save ( materialQualityEntity );
            if ( ! save ) {
                return AjaxResult.error ( "新增物料质量信息失败" );
            }
        }
        //物料计划属性&计划控制基本信息
        if ( ! ObjectUtils.isEmpty ( materialAddDto.getMaterialPlanAttribute () ) ) {
            MaterialPlanAttributeEntity materialPlanAttributeEntity = materialAddDto.getMaterialPlanAttribute ();
            materialPlanAttributeEntity.setMaterialId ( materialEntity.getId () );
            materialPlanAttributeEntity.setCreateTime ( nowDate );
            materialPlanAttributeEntity.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
            boolean save = materialPlanAttributeService.save ( materialPlanAttributeEntity );
            if ( ! save ) {
                return AjaxResult.error ( "新增物料计划属性&计划控制信息失败" );
            }
        }
        materialEntity.setDeptId ( CurrentUserUtil.getCompanyId () );
//        StartProcessDto startDto = new StartProcessDto().setBusinessId(materialId).setBusinessType(materialEntity.getBusinessType()).setModelId(materialEntity.getModelId())
//                .setBusinessName("物料_".concat(materialId));
//        String instanceId = actModelService.startProcess(startDto);
//        materialEntity.setInstanceId(instanceId);
        if ( StringUtils.isEmpty ( materialEntity.getMaterialCode () ) ) {
            String companyId = CurrentUserUtil.getCompanyId ();
            SysDept sysDept = sysDeptService.getById ( companyId );
            int count = this.count ();
            String countStr = String.format ( "%06d", count );
            String firstLetter = ChineseToPinyin.getFirstLetter ( sysDept.getDeptName () );
            String orderNumber = firstLetter.concat ( "_WLBM_" ).concat ( countStr );
            materialEntity.setMaterialCode ( orderNumber );
        }
        boolean save = this.save ( materialEntity );
        if ( ! save ) {
            return AjaxResult.error ( "新增物料基本信息失败" );
        } else {
            return AjaxResult.success ( "添加成功" );
        }
    }

    /**
     * 修改物料信息
     * @param materialEntity 物料信息
     * @return 结果
     */
    @Override
    @Transactional (rollbackFor = Exception.class)
    public AjaxResult updateMaterialEntity (MaterialEntity materialEntity) {
        if ( ObjectUtils.isEmpty ( materialEntity ) ) {
            return AjaxResult.error ( "物料实体不能为空" );
        }
        // 更新关联实体
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialInventoryEntity () ) ) {
            materialInventoryService.updateById ( materialEntity.getMaterialInventoryEntity () );
        }
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialProcureEntity () ) ) {
            materialProcureService.updateById ( materialEntity.getMaterialProcureEntity () );
        }
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialSaleEntity () ) ) {
            materialSaleService.updateById ( materialEntity.getMaterialSaleEntity () );
        }
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialProductEntity () ) ) {
            materialProductService.updateById ( materialEntity.getMaterialProductEntity () );
        }
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialQualityEntity () ) ) {
            materialQualityService.updateById ( materialEntity.getMaterialQualityEntity () );
        }
        if ( ! ObjectUtils.isEmpty ( materialEntity.getMaterialPlanAttributeEntity () ) ) {
            materialPlanAttributeService.updateById ( materialEntity.getMaterialPlanAttributeEntity () );
        }
        // 更新物料基本信息
        boolean update = this.updateById ( materialEntity );
        if ( ! update ) {
            log.error ( "修改物料基本信息失败" );
            return AjaxResult.error ( "修改物料基本信息失败" );
        } else {
            return AjaxResult.success ( "修改成功" );
        }

    }

    /**
     * 批量删除物料信息
     * @param ids 需要删除的物料信息主键
     * @return 结果
     */
    @Override
    @Transactional (rollbackFor = Exception.class)
    public AjaxResult deleteMaterialEntityByIds (String[] ids) {
        List<String> idList = Arrays.asList ( ids );
        if ( idList.isEmpty () ) {
            return AjaxResult.success ();
        }
        materialInventoryService.remove (
                Wrappers.lambdaQuery ( MaterialInventoryEntity.class )
                        .in ( MaterialInventoryEntity :: getMaterialId, idList )
        );
        materialProcureService.remove (
                Wrappers.lambdaQuery ( MaterialProcureEntity.class )
                        .in ( MaterialProcureEntity :: getMaterialId, idList )
        );
        materialProductService.remove (
                Wrappers.lambdaQuery ( MaterialProductEntity.class )
                        .in ( MaterialProductEntity :: getMaterialId, idList )
        );
        materialQualityService.remove (
                Wrappers.lambdaQuery ( MaterialQualityEntity.class )
                        .in ( MaterialQualityEntity :: getMaterialId, idList )
        );
        materialPlanAttributeService.remove (
                Wrappers.lambdaQuery ( MaterialPlanAttributeEntity.class )
                        .in ( MaterialPlanAttributeEntity :: getMaterialId, idList )
        );
        materialSaleService.remove (
                Wrappers.lambdaQuery ( MaterialSaleEntity.class )
                        .in ( MaterialSaleEntity :: getMaterialId, idList )
        );

        this.removeByIds ( idList );

        return AjaxResult.success ();
    }

    /**
     * 删除物料信息信息
     * @param id 物料信息主键
     * @return 结果
     */
    @Override
    public int deleteMaterialEntityById (String id) {
        return materialEntityMapper.deleteMaterialEntityById ( id );
    }

    @Override
    public AjaxResult selectMaterialEntityListByParentId (MaterialEntity materialEntity) {
        materialEntity.setPage ( ( materialEntity.getPage () - 1 ) * materialEntity.getLimit () );
        List<MaterialEntity> list = materialEntityMapper.selectPageList ( materialEntity );
        Integer integer = materialEntityMapper.selectPageCount ( materialEntity );
        PageParam pageParam = new PageParam ();
        pageParam.setRecords ( list ).setTotal ( integer );
        return AjaxResult.success ( pageParam );
    }

    /**
     * 模糊查询，供其他新增页面引用
     * @param materialEntity
     * @return
     */
    @Override
    public AjaxResult queryList (MaterialEntity materialEntity) {
        LambdaQueryWrapper<MaterialEntity> queryWrapper = new LambdaQueryWrapper<> ();
        if ( StringUtils.isNotBlank ( materialEntity.getAllowProduce () ) ) {
            queryWrapper.eq ( MaterialEntity :: getAllowProduce, materialEntity.getAllowProduce () );
        }
        if ( StringUtils.isNotBlank ( materialEntity.getMaterialProperty () ) ) {
            queryWrapper.eq ( MaterialEntity :: getMaterialProperty, materialEntity.getMaterialProperty () );
        }
        Page<MaterialEntity> page = this.page ( new Page<> ( materialEntity.getPage (), materialEntity.getLimit () ), queryWrapper );
        SysDept sysDept = sysDeptService.getById ( CurrentUserUtil.getCompanyId () );
        List<MaterialEntity> records = page.getRecords ();
        //做属性名变更，送到前端
        List<ImportMaterialVo> vos = new ArrayList<> ();
        //查询单位名称
        List<String> ids = records.stream ().map ( MaterialEntity :: getUnit ).collect ( Collectors.toList () );
        List<KingBaseMeteringUnitEntity> list = iKingBaseMeteringUnitService.list ( new LambdaQueryWrapper<KingBaseMeteringUnitEntity> ().
                in ( KingBaseMeteringUnitEntity :: getMeteringUnitCode, ids ) );
        //通过物料的默认税率编码，查询税率值
        List<String> taxRateCode = records.stream ().map ( MaterialEntity :: getDefaultTaxRate ).collect ( Collectors.toList () );
        System.out.println ( taxRateCode );
        List<KingBaseTaxRateEntity> kingBaseTaxRateEntities = iKingBaseTaxRateService.list ( new LambdaQueryWrapper<KingBaseTaxRateEntity> ().in ( KingBaseTaxRateEntity :: getRateCode, taxRateCode ) );
        records.forEach ( material -> {
            ImportMaterialVo vo = new ImportMaterialVo ();
            //通过单位code取单位汉字
            String unitName = "";
            for ( KingBaseMeteringUnitEntity kingBaseMeteringUnitEntity : list ) {
                if ( material.getUnit ().equals ( kingBaseMeteringUnitEntity.getMeteringUnitCode () ) ) {
                    unitName = kingBaseMeteringUnitEntity.getMeteringUnitName ();
                }
            }
            //解析税率值
            String rate = "";
            for ( KingBaseTaxRateEntity kingBaseTaxRateEntity : kingBaseTaxRateEntities ) {
                if ( kingBaseTaxRateEntity.getRateCode ().equals ( material.getDefaultTaxRate () ) ) {
                    rate = kingBaseTaxRateEntity.getRate ();
                }
            }
            vo.setId ( material.getId () ).
                    setRate ( rate ).
                    setMaterialName ( material.getMaterialName () ).
                    setMaterialCode ( material.getMaterialCode () ).
                    setPurchaseUnit ( material.getUnit () ).
                    setPurchaseUnitName ( unitName ).
                    setPricingUnit ( material.getUnit () ).
                    setPricingUnitName ( unitName ).
                    setModel ( material.getModel () ).
                    setReceivingDeptName ( sysDept.getDeptName () ).
                    setSettlementDeptName ( sysDept.getDeptName () ).
                    setRequireDeptName ( sysDept.getDeptName () ).
                    setMaterialProperty ( material.getMaterialProperty () );
            vos.add ( vo );
        } );
        PageParam pageParam = new PageParam ();
        pageParam.setRecords ( vos );
        pageParam.setTotal ( page.getTotal () );
        pageParam.setCurrent ( page.getCurrent () );
        pageParam.setSize ( page.getSize () );
        pageParam.setPages ( page.getPages () );
        return AjaxResult.success ( pageParam );
    }

    /**
     * 禁用物料
     * @param id
     * @return
     */
    @Override
    public AjaxResult disabled (String id) {
        try {
            MaterialEntity materialEntity = this.getById ( id );
            boolean update = this.update ( new LambdaUpdateWrapper<MaterialEntity> ()
                                                   .set ( MaterialEntity :: getIsDisabled, materialEntity.getIsDisabled ().equals ( "1" ) ? "2" : "1" )
                                                   .eq ( MaterialEntity :: getId, id )
            );

            if ( ! update ) {
                String message = materialEntity.getIsDisabled ().equals ( "1" ) ? "禁用失败" : "解禁失败";
                return AjaxResult.error ( message );
            }

            String successMessage = materialEntity.getIsDisabled ().equals ( "1" ) ? "禁用成功" : "解禁成功";
            return AjaxResult.success ( successMessage );
        } catch ( Exception e ) {
            // 记录异常日志
            log.error ( "更新状态时发生异常", e );
            return AjaxResult.error ( "操作失败，请稍后重试" );
        }
    }


}
